
// 从 'url' 模块导入 fileURLToPath，用于将 import.meta.url 转换为文件路径
import { fileURLToPath } from 'url';
// 从 'path' 模块导入 dirname，用于获取文件所在目录
import { dirname } from 'path';
// 从 'child_process' 模块导入 exec，用于执行 shell 命令
import { exec } from 'child_process';
// 从 'util' 模块导入 promisify，用于将回调风格的函数转换为 Promise 风格
import { promisify } from 'util';

// 将 exec 函数转换为返回 Promise 的异步函数，方便使用 async/await
const execAsync = promisify(exec);

/**
 * 异步执行 shell 命令，并返回标准输出内容。
 * @param {string} cmd - 要执行的命令字符串
 * @param {string} cwd - 命令执行的工作目录
 * @returns {Promise<string>} - 命令执行后的标准输出内容
 */
export async function runCommand(cmd, cwd) {
  try {
    // 执行命令，指定工作目录和编码，忽略标准输入，捕获标准输出和错误输出
    const stdout = await execAsync(cmd, {
      cwd,
      encoding: 'utf-8',
      stdio: ['ignore', 'pipe', 'pipe'],
    });
    // 返回命令的标准输出内容（如 audit 的 JSON 结果）
    return stdout.stdout.toString();
  } catch (err) {
    // 如果有标准输出，返回标准输出内容（即使命令报错）
    if (err.stdout) {
      return err.stdout.toString();
    }
    // 其他错误则抛出
    throw err;
  }
}

/**
 * 生成一个较为唯一的字符串 ID，结合了随机数和当前时间戳。
 * @returns {string} - 唯一 ID 字符串
 */
export function uniqueId() {
  // Math.random() 生成随机小数，toString(36) 转为36进制字符串，substring(2, 15) 去掉'0.'取13位
  // Date.now() 获取当前时间戳，toString(36) 转为36进制字符串
  // 拼接后得到唯一性较高的字符串
  return Math.random().toString(36).substring(2, 15) + Date.now().toString(36);
}

/**
 * 获取当前模块的文件名（绝对路径）。
 * @param {string} importMetaUrl - import.meta.url 字符串
 * @returns {string} - 文件的绝对路径
 */
export function getFilename(importMetaUrl) {
  return fileURLToPath(importMetaUrl);
}

/**
 * 获取当前模块所在的目录名（绝对路径）。
 * @param {string} importMetaUrl - import.meta.url 字符串
 * @returns {string} - 目录的绝对路径
 */
export function getDirname(importMetaUrl) {
  return dirname(getFilename(importMetaUrl));
}
